﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;


namespace TestMySqlConnetPoll
{
    public class objRevAnalogType
    {
        //public string AnalogTypeName;
        public byte AnalogType;
        public List<Int16> ValueList = new List<short>();
    }
    public class objRevCommandType
    {
        public int type;
        public int length;
        public List<byte> value = new List<byte>();
    }
    public class objRevLkType
    {
        public string LkTypeName;
        public List<byte> ValueList = new List<byte>();
    }
    //public class objRevAlarmType
    //{
    //    public int u_time;      //报警开始时间
    //    public int Level;       //报警级别
    //    public int alarmType;   //报警类型
    //    public int extype;      //扩展类型
    //    public int devType;     //设备类型，模拟量、开关量、
    //    public int devNo;       //报警设备
    //    public int statue;      //报警设备状态
    //    public int tcFlag;      //天窗修标志
    //    public int dtime;       //报警延迟时间
    //    public int etime;       //报警结束时间
    //    public string AlarmText; //报警明文
    //}

    public class objRevGybdcQxType
    {
        public int devNo = -1;
        public int time = 0;
        public int dotNum = -1;
        public List<byte> v = new List<byte>();
    }

    public struct objCmdModifyCfgType
    {
        public byte AnalogType;    //模拟量类型
        public Int16 AnalogNo;     //模拟量序号
        public float Before_Up;    //修改前上限
        public float Before_Low;   //修改前下限
        public float Before_flup;  //修改前分路上限
        public float Modified_Up;   //修改后上限
        public float Modified_Low; //修改后下限
        public float Modified_flup; //修改后分路下限
        public float CurrentValue; //当前值
        public float TargetValue;  //目标值
    }

    public class objCmdModifyCfg   //修改配置命令结构
    {
        public byte type = 0;
        public Int16 MondifyNum = 0;
        public List<objCmdModifyCfgType> MondifyValue = new List<objCmdModifyCfgType>();
    }
    public class objJySelcetCmd     //绝缘选测结构
    {
        public byte type = 0;
        public Int16 length = 0;
        public Int16 TestNum = 0;
        public List<int> TestNoList = new List<int>();
    }

    public struct objJyAllTestCmd   //绝缘全测命令结构
    {
        public byte type;
        public Int16 length;
    }

    public struct objLlTestCmd      //漏流测试命令结构
    {
        public byte type;
        public Int16 length;
        public Int16 TestNo;
    }

    [Serializable]
    public class objRevKGL
    {
        public bool AllFlag = false;    //全体开关量标记
        public int kglNum = 0;
        public int time = 0;
        public List<byte> Value = new List<byte>();
    }

    //public class objAlarmConfirm    //报警确认结构
    //{
    //    public byte type = 0;
    //    public Int16 length = 0;
    //    public Int16 ConfirmNum = 0;
    //    public List<ObjAlaram> AlarmList = new List<ObjAlaram>();
    //}

    public static class c_SendData
    {
        //#region 内存映射文件，废弃
        ////内存映射文件的发送未写完，不能用
        //static public bool WirteMemoryFileTime()
        //{
        //    DateTime time = DateTime.Now;
        //    int t = (int)MySql.DateTimeToTime_t(time);
        //    byte[] a = BitConverter.GetBytes(t);
        //    return c_ReceiveData.WriteMeroryMappiong(c_ReceiveData.MF_SysTimeAddr + 4, 4, a);
        //}

        //static public bool WriteMemoryFile_UserInfo(int ID, string Name)
        //{
        //    byte[] a = new byte[30];
        //    a[0] = (byte)(ID & 0xff);
        //    a[1] = (byte)(ID >> 8 & 0xff);
        //    byte[] b = System.Text.Encoding.Default.GetBytes(Name);
        //    for (int i = 0; i < b.Length; i++)
        //    {
        //        if (i > 20) break;
        //        a[2 + i] = b[i];
        //    }
        //    return c_ReceiveData.WriteMeroryMappiong(c_ReceiveData.MF_CurrentUserAddr, 22, a);
        //}

        //static public bool WriteToMemoryFlieCommandInfo(int type, object o)
        //{
        //    byte[] OutBuf = new byte[5000];
        //    if (type == 1)   //修改配置
        //    {
        //        objCmdModifyCfg obj = (objCmdModifyCfg)o;
                
        //        int MondfyNum = obj.MondifyNum;
        //        if (MondfyNum != obj.MondifyValue.Count) return false;
        //        OutBuf[0] = (byte)(MondfyNum & 0xff);
        //        OutBuf[1] = (byte)(MondfyNum >> 8 & 0xff);
        //        OutBuf[3] = (byte)type;
        //        foreach (objCmdModifyCfgType key in obj.MondifyValue)
        //        {

        //        }
        //    }
        //    return false;
        //}
        //#endregion
        //----------------------以下为管道发送
        static public bool SendHartData()
        {
            byte[] t = new byte[10];
            t[0] = 0x7f;
            t[1] = 0x00;
            for(int i = 2;i<10;i++)
            {
                t[i] = 0xff; 
            }
            return C_MyPipe.WritePipeData(t, 10);
        }
        /// <summary>
        /// 发送修改配置命令，可以一次修改多条
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        static public bool SendCmdModifyCFG(List<objCmdModifyCfgType> obj)
        {
            int Num = obj.Count;
            List<byte> t = new List<byte>();
            
            t.Add(0x7f);
            t.Add(0x01);
            t.Add((byte)Num);
            t.Add((byte)(Num << 16));
            
            foreach(objCmdModifyCfgType key in obj)
            {
                t.Add(key.AnalogType);
                t.Add((byte)key.AnalogNo);
                t.Add((byte)(key.AnalogNo>>8));
                
                string b_up = key.Before_Up.ToString();
                byte[] upbuf = System.Text.Encoding.Default.GetBytes(b_up);
                int upLen = upbuf.Length;
                t.Add((byte)upLen);
                t.AddRange(upbuf);

                string b_dn = key.Before_Low.ToString();
                byte[] dnbuf = System.Text.Encoding.Default.GetBytes(b_dn);
                int dnLen = dnbuf.Length;
                t.Add((byte)dnLen);
                t.AddRange(dnbuf);
                
                string fb_dn = key.Before_flup.ToString();
                byte[] fdnbuf = System.Text.Encoding.Default.GetBytes(fb_dn);
                int fdnLen = fdnbuf.Length;
                t.Add((byte)fdnLen);
                t.AddRange(fdnbuf);

                string mb_up = key.Modified_Up.ToString();
                byte[] mupbuf = System.Text.Encoding.Default.GetBytes(mb_up);
                int mupLen = mupbuf.Length;
                t.Add((byte)mupLen);
                t.AddRange(mupbuf);

                string mb_dn = key.Modified_Low.ToString();
                byte[] mdnbuf = System.Text.Encoding.Default.GetBytes(mb_dn);
                int mdnLen = mdnbuf.Length;
                t.Add((byte)mdnLen);
                t.AddRange(mdnbuf);


                string mfb_dn = key.Modified_flup.ToString();
                byte[] mfdnbuf = System.Text.Encoding.Default.GetBytes(mfb_dn);
                int mfdnLen = mfdnbuf.Length;
                t.Add((byte)mfdnLen);
                t.AddRange(mfdnbuf);

                string cv = key.CurrentValue.ToString();
                byte[] cbuf = System.Text.Encoding.Default.GetBytes(cv);
                int cvLen = cbuf.Length;
                t.Add((byte)cvLen);
                t.AddRange(cbuf);

                string tv = key.TargetValue.ToString();
                byte[] tbuf = System.Text.Encoding.Default.GetBytes(tv);
                int tvLen = tbuf.Length;
                t.Add((byte)tvLen);
                t.AddRange(tbuf);                        
            }
            bool b = C_MyPipe.WritePipeData(t.ToArray(),t.Count);
            return b;
        }
        /// <summary>
        /// 发送绝缘选测命令
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        static public bool SendCmdJySelectTest(List<string> obj)
        {
            int Num = obj.Count;
            byte[] t = new byte[Num * 2 + 20];
            t[0] = 0x7f;
            t[1] = 0x02;
            t[2] = (byte)Num;
            t[3] = (byte)(Num >> 8);
            int m = 4;
            foreach(string keystring in obj)
            {
                int key = c_Device.GetJyLlCyDevNo("电缆绝缘", keystring);
                t[m++] = (byte)key;
                t[m++] = (byte)(key >> 8);
            }
            bool b = C_MyPipe.WritePipeData(t, m);
            return b;
        }
        /// <summary>
        /// 绝缘全测命令
        /// </summary>
        /// <returns></returns>
        static public bool SendCmdJyAllTest()
        {
            byte[] t = new byte[2];
            t[0] = 0x7f;
            t[1] = 0x03;
            bool b = C_MyPipe.WritePipeData(t, 2);
            return b;
        }
        /// <summary>
        /// 漏流测试命令
        /// </summary>
        /// <param name="xNo"></param> 测试序号
        /// <returns></returns>
        static public bool SendCmdLlTest(string xstring)
        {
            byte[] t = new byte[4];
            t[0] = 0x7f;
            t[1] = 0x04;
            int xNo = c_Device.GetJyLlCyDevNo("电源漏流", xstring);
            t[2] = (byte)xNo;
            t[3] = (byte)(xNo >> 8);
            bool b = C_MyPipe.WritePipeData(t, 4);
            return b;
        }
        /// <summary>
        /// 高压不对称曲线测试命令
        /// </summary>
        /// <param name="xNo"></param> 测试设备编号
        /// <returns></returns>
        static public bool SendCmdGyqxTest(string xstring)
        {
            c_RealTimeValue.RevRealTimeGYBDCqx.Clear(); //发送命令时清除数据
            byte[] t = new byte[4];
            t[0] = 0x7f;
            t[1] = 0x06;
            int xNo = c_Device.GetGybdcDyDevNo(xstring);
            t[2] = (byte)xNo;
            t[3] = (byte)(xNo >> 8);
            bool b = C_MyPipe.WritePipeData(t, 4);
            return b;
        }
        static public bool SendAffirmAlarmData(List<ObjAlaram>obj)
        {
            int Num = obj.Count;
            List<byte> t = new List<byte>();
            t.Add(0x7f);
            t.Add(0x05);
            t.Add((byte)Num);
            t.Add((byte)(Num >> 8));            
            foreach (ObjAlaram key in obj)
            {
                List<byte> rt = MySql.objAlarmToByteBuf(key, 0, 0);
                t.AddRange(rt);
            }
            bool b = C_MyPipe.WritePipeData(t.ToArray(), t.Count);
            return b;
        }
    }

    public static class c_ReceiveData     //接收数据类，从内存映射文件或者从网络接收数据
    {
        #region 外部变量定义
        
        /// <summary>
        /// 接收模拟表
        /// </summary>
        //static public Queue<objRevAnalogType> RevAnalogQueue = new Queue<objRevAnalogType>();
        /// <summary>
        /// 接收开关量表
        /// </summary>
        //static public Queue<objRevKGL> RevKGLQueue = new Queue<objRevKGL>();
        /// <summary>
        /// 使用消息替代 报警队列
        /// </summary>
        static public event EventHandler NewAlarmEvent;
        static public event EventHandler NewStatueInfo;
        static public event EventHandler NewLkInfo;
        static public event EventHandler NewCommandRet;
        static public event EventHandler NewKglEvent;
        static public event EventHandler NewAnalogEvent;
        static public System.Timers.Timer Time_CheckSendSevAlarm = new System.Timers.Timer();
        /// <summary>
        /// 发送给服务器的报警数据，用于检查是否有回执，如果3分钟内没有收到回执，则再次发送
        /// </summary>
        static private List<objSendAlarmData> SendSevAlarmData = new List<objSendAlarmData>();
        /// <summary>
        /// 接收报警数据
        /// </summary>
        //static public Queue<ObjAlaram> RevAlarmQueue = new Queue<ObjAlaram>();
        /// <summary>
        /// 接收命令回执数据，包括修改配置，报警确认回执，绝缘测试回执，漏流测试回执
        /// </summary>
        //static public Queue<objRevCommandType> RevCommandRet = new Queue<objRevCommandType>();
        /// <summary>
        /// 接收列控实时数据.
        /// </summary>
        //static public Queue<objRevLkType> RevLkQueue = new Queue<objRevLkType>();
        /// <summary>
        /// 接收高压不对称曲线值
        /// </summary>
        //static public Queue<objRevGybdcQxType> RevGybdcQxQueue = new Queue<objRevGybdcQxType>();

        #endregion

        //#region 内存映射文件常量定义
        //public const string MF_MappingName = "CSM2010MEMORYFILE";                      //常量，内存映射文件名
        //public const int MK_DisCommandFlag = 0;
        //public const int MK_LogicCommandFlag = 1;
        //public const int MK_LK_Flag = 2;
        //public const int MK_AlarmFlag = 3;
        //public const int MK_KGL_Flag = 4;
        //public const int MK_AnalogFlag = 5;
        //public const int MK_GybdcqxFlag = 6;
        //public const int MF_SysTimeAddr = 20;                                          //逻辑处理进程时间和显示进程时间开始地址   0~7
        //public const int MF_CurrentUserAddr = MF_SysTimeAddr + 8;                      //当前用户信息开始地址   8~50
        //public const int MF_OperateCommandAddr = 50;                  //显示层操作命令开始地址 50~4000
        //public const int MF_CommandRetAddr = 4000;                     //逻辑处理层响应命令回执数据地址 4000~8000
        //public const int MF_LkInfoAddr = 8000;                         //列控信息开始地址 8000~18000
        //public const int MF_AlarmInfoAddr = 18000;                     //报警信息开始地址 18000~318000
        //public const int MF_KGL_Addr = 300 * 1000 + 18000;               //开关量开始地址  318000~321000
        //public const int MF_AnalogAddr = MF_KGL_Addr + 3000;                           //模拟量开始地址 321000~
        //public const int MF_GybdcqxAddr = MF_AnalogAddr + 40000;       //高压不对称曲线实时值开始地址
        //private const int FILE_MAP_COPY = 0x0001;
        //private const int FILE_MAP_WRITE = 0x0002;
        //private const int FILE_MAP_READ = 0x0004;
        //private const int INVALID_HANDLE_VALUE = -1;

        //#endregion
        //#region 内存映射文件，废弃
        //#region WIN32函数引用定义
        //[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
        //public static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr lpSecurityAttributes,
        //                                        int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);

        //[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
        //public static extern IntPtr CreateFileMapping(int hFile, IntPtr lpAttributes, int flProtect,
        //                                                int dwMaximumSizeLow, int dwMaximumSizeHigh, string lpName);

        //[DllImport("kernel32", SetLastError = true)]
        //public static extern bool FlushViewOfFile(IntPtr lpBaseAddress, IntPtr dwNumBytesToFlush);

        //[DllImport("kernel32", SetLastError = true)]
        //public static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject, int dwDesiredAccess, int dwFileOffsetHigh,
        //                                            int dwFileOffsetLow, IntPtr dwNumBytesToMap);

        //[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)]
        //public static extern IntPtr OpenFileMapping(int dwDesiredAccess, bool bInheritHandle, string lpName);

        //[DllImport("kernel32", SetLastError = true)]
        //public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);

        //[DllImport("kernel32", SetLastError = true)]
        //public static extern bool CloseHandle(IntPtr handle);
        //#endregion
        ///// <summary>
        ///// 处理逻辑层传过来的模拟量信息
        ///// </summary>
        ///// <param name="Buf"></param>
        //static private void DisposeAnalogData(byte[] Buf)
        //{
        //    int Length = Buf[0] + Buf[1] * 256;             //模拟量数据总长度
        //    int Offset = 2;
        //    while (true)
        //    {
        //        if (Offset >= Length) break;
        //        byte AnalogType = Buf[Offset++];            //模拟量类型
        //        if (!c_Device.IsValidAnalogType(AnalogType))
        //        {
        //            Console.WriteLine("模拟量类型错误");
        //            break;
        //        }
        //        int AnalogLength = Buf[Offset] + Buf[Offset + 1];   //单项模拟量长度
        //        Offset += 2;
        //        objRevAnalogType tmp = new objRevAnalogType();
        //        string KeyString = c_Device.GetAnalogTypeName((AnalogCodeType)AnalogType);
        //        //tmp.AnalogTypeName = KeyString;
        //        tmp.AnalogType = AnalogType;
        //        for (int i = 0; i < AnalogLength; i++)
        //        {
        //            Int16 TmpValue = (Int16)(Buf[Offset] + Buf[Offset + 1] * 256);
        //            tmp.ValueList.Add(TmpValue);
        //            Offset += 2;
        //        }
        //        lock (RevAnalogQueue)
        //        {
        //            RevAnalogQueue.Enqueue(tmp);
        //        }
        //    }
        //}
        ///// <summary>
        ///// 处理实时开个量
        ///// </summary>
        ///// <param name="Buf"></param>
        //static private void DisposeKglData(byte[] Buf)
        //{
        //    int m = 0;            
        //    objRevKGL t = new objRevKGL();
        //    t.time = Buf[m] + (Buf[m + 1] << 8) + (Buf[m + 2] << 16) + (Buf[m + 3] << 24);
        //    m += 4;
        //    t.kglNum = Buf[m] + (Buf[m + 1] << 8);
        //    m += 2;
        //    int Length = Buf[m] + (Buf[m + 1] << 8);             //开关量数据总长度      
        //    m += 2;
        //    for (int i = 0; i < Length; i++)
        //    {
        //        t.Value.Add(Buf[m + i]);
        //    }
        //    lock (RevKGLQueue)
        //    {
        //        RevKGLQueue.Enqueue(t);
        //    }
        //}

        //static private void DisposeLkData(byte[] Buf)
        //{
        //    objRevLkType obj = new objRevLkType();
        //    obj.LkTypeName = "硬件平台";
        //    byte[] tmpBuf = new byte[1024];
        //    Array.Copy(Buf, 0, tmpBuf, 0, 1024);
        //    obj.ValueList = tmpBuf.ToList();
        //    lock (RevLkQueue)
        //    {
        //        RevLkQueue.Enqueue(obj);
        //        int m = 1024;
        //        for (int i = 0; i < 11; i++)
        //        {
        //            m = m + i * 512;
        //            if (i == 0) obj.LkTypeName = "联锁接口进路信息";
        //            else if (i == 1) obj.LkTypeName = "联锁改方命令信息";
        //            else if (i == 2) obj.LkTypeName = "联锁改方回执信息";
        //            else if (i == 3) obj.LkTypeName = "站间改方命令";
        //            else if (i == 4) obj.LkTypeName = "站间改方回执";
        //            else if (i == 5) obj.LkTypeName = "站间边界信息";
        //            else if (i == 6) obj.LkTypeName = "临时限速状态";
        //            else if (i == 7) obj.LkTypeName = "轨道区段编码信息";
        //            else if (i == 8) obj.LkTypeName = "状态全体信息";
        //            else if (i == 9) obj.LkTypeName = "应答器报文编码信息";
        //            else if (i == 10) obj.LkTypeName = "无配线站方向口信息";
        //            byte[] tb = new byte[512];
        //            Array.Copy(Buf, m, tb, 0, 512);
        //            obj.ValueList = tb.ToList();
        //            RevLkQueue.Enqueue(obj);
        //        }
        //    }
        //}

        //static private void DisposeAlarmData(byte[] Buf)
        //{
        //    List<ObjAlaram> li = MySql.byteBufToObjAlarmList(Buf, 0, 0, 0);
        //    lock (RevAlarmQueue)
        //    {
        //        for (int i = 0; i < li.Count; i++)
        //        {
        //            RevAlarmQueue.Enqueue(li[i]);
        //        }
        //    }
        //}

        //static private void DisposeCommandRet(byte[] Buf)   //处理逻辑层对命令的回执
        //{
        //    int Num = Buf[0];             //命令条数
        //    objRevCommandType tmp = new objRevCommandType();
        //    int m = 1;
        //    lock (RevCommandRet)
        //    {
        //        for (int i = 0; i < Num; i++)
        //        {
        //            tmp.type = Buf[m++];  //命令类型
        //            int t0 = Buf[m++];
        //            int t1 = Buf[m++];
        //            tmp.length = (t1 << 8) + t0;
        //            for (int k = 0; k < tmp.length; k++)
        //            {
        //                tmp.value.Add(Buf[m++]);
        //            }
        //            RevCommandRet.Enqueue(tmp);
        //        }
        //    }
        //}

        //static private void DisposeGybdcqxData(byte[] Buf)
        //{
        //    objRevGybdcQxType obj = new objRevGybdcQxType();
        //    obj.devNo = Buf[0] + (Buf[1] << 8);
        //    obj.time = Buf[2] + (Buf[3] << 8) + (Buf[4] << 16) + (Buf[5] << 24);
        //    obj.dotNum = Buf[6] + (Buf[7] << 8);
        //    int m = 8;
        //    for (int i = 0; i < obj.dotNum * 2; i++)
        //    {
        //        obj.v.Add(Buf[m++]);
        //    }
        //    lock (RevGybdcQxQueue)
        //    {
        //        RevGybdcQxQueue.Enqueue(obj);
        //    }
        //}

        //static private void DisposeMemoryMappingData(int type, byte[] MemoryBuf)
        //{
        //    switch (type)
        //    {
        //        case 0:         //时间
        //            break;
        //        case 1:         //逻辑处理层对命令的回执
        //            DisposeCommandRet(MemoryBuf);
        //            break;
        //        case 2:         //LK
        //            DisposeLkData(MemoryBuf);
        //            break;
        //        case 3:         //报警
        //            DisposeAlarmData(MemoryBuf);
        //            break;
        //        case 4:         //开关量
        //            DisposeKglData(MemoryBuf);
        //            break;
        //        case 5:         //模拟量
        //            DisposeAnalogData(MemoryBuf);
        //            break;
        //        case 6:
        //            DisposeGybdcqxData(MemoryBuf);
        //            break;
        //    }
        //}

        //static public void ReadMemoryMapping()
        //{
        //    IntPtr handle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, false, MF_MappingName);
        //    if (handle != IntPtr.Zero)
        //    {
        //        IntPtr mappingFile = MapViewOfFile(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, new IntPtr(0));
        //        if (IntPtr.Zero != mappingFile)
        //        {
        //            byte[] WRFlag = new byte[20];           //首先读取读写标志，20字节
        //            IntPtr ActivePtr = mappingFile + 0;
        //            try
        //            {
        //                Marshal.Copy(ActivePtr, WRFlag, 0, 20);
        //            }
        //            catch
        //            {
        //                MessageInfo(null, new MessageInfoEventArgs("读内存映射文件失败，逻辑进程"));
        //            }
        //            int LogicCommandFlag = WRFlag[1];
        //            int LKcommandFlag = WRFlag[2];
        //            int AlarmFlag = WRFlag[3];
        //            int kglFlag = WRFlag[4];
        //            int analogFlag = WRFlag[5];
        //            int gybdcqxFlag = WRFlag[6];
        //            //-------------------------------------------------------------
        //            bool NeedRead = false;
        //            int WriteAddr = 0;
        //            int StartAddr = 0;
        //            int Length = 0;
        //            for (int i = 0; i < 7; i++)
        //            {
        //                switch (i)
        //                {
        //                    case 0:
        //                        StartAddr = MF_SysTimeAddr;
        //                        Length = 4;
        //                        NeedRead = true;
        //                        break;
        //                    case 1:
        //                        StartAddr = MF_CommandRetAddr;
        //                        Length = MF_LkInfoAddr - MF_CommandRetAddr;
        //                        if (LogicCommandFlag == 1)
        //                        {
        //                            NeedRead = true;
        //                            WriteAddr = MK_LogicCommandFlag;
        //                        }
        //                        break;
        //                    case 2:
        //                        StartAddr = MF_LkInfoAddr;
        //                        Length = MF_AlarmInfoAddr - MF_LkInfoAddr;
        //                        if (LKcommandFlag == 1)
        //                        {
        //                            NeedRead = true;
        //                            WriteAddr = MK_LK_Flag;
        //                        }
        //                        break;
        //                    case 3:
        //                        StartAddr = MF_AlarmInfoAddr;
        //                        Length = MF_KGL_Addr - MF_AlarmInfoAddr;
        //                        if (AlarmFlag == 1)
        //                        {
        //                            NeedRead = true;
        //                            WriteAddr = MK_AlarmFlag;
        //                        }
        //                        break;
        //                    case 4:
        //                        StartAddr = MF_KGL_Addr;
        //                        Length = MF_AnalogAddr - MF_KGL_Addr;
        //                        if (kglFlag == 1)
        //                        {
        //                            NeedRead = true;
        //                            WriteAddr = MK_KGL_Flag;
        //                        }
        //                        break;
        //                    case 5:
        //                        StartAddr = MF_AnalogAddr;
        //                        Length = MF_AnalogAddr + 40000;
        //                        if (analogFlag == 1)
        //                        {
        //                            NeedRead = true;
        //                            WriteAddr = MK_AnalogFlag;
        //                        }
        //                        break;
        //                    case 6:
        //                        StartAddr = MF_GybdcqxAddr;
        //                        Length = MF_GybdcqxAddr + 20000;
        //                        if (gybdcqxFlag == 1)
        //                        {
        //                            NeedRead = true;
        //                            WriteAddr = MK_GybdcqxFlag;
        //                        }
        //                        break;
        //                }
        //                if (NeedRead)
        //                {
        //                    //-----读数据
        //                    byte[] msg = new byte[600 * 1024];
        //                    ActivePtr = mappingFile + StartAddr;
        //                    try
        //                    {
        //                        Marshal.Copy(ActivePtr, msg, 0, Length);
        //                    }
        //                    catch
        //                    {
        //                        MessageInfo(null, new MessageInfoEventArgs("读逻辑进程内存映射文件失败"));
        //                    }
        //                    DisposeMemoryMappingData(i, msg);
        //                    //-----写已经读取标志
        //                    byte[] kk = new byte[1];
        //                    kk[0] = 2;
        //                    IntPtr AcPtr = mappingFile + WriteAddr;
        //                    try
        //                    {
        //                        Marshal.Copy(kk, 0, AcPtr, 1);
        //                        FlushViewOfFile(AcPtr, new IntPtr(1));
        //                    }
        //                    catch
        //                    {
        //                        MessageInfo(null, new MessageInfoEventArgs("写逻辑进程内存映射文件失败"));
        //                    }
        //                }
        //            }
        //            try
        //            {
        //                UnmapViewOfFile(ActivePtr);
        //                UnmapViewOfFile(mappingFile);
        //            }
        //            catch
        //            {
        //                MessageInfo(null, new MessageInfoEventArgs("关闭逻辑进程内存映射文件指针失败"));
        //            }
        //        }
        //        try
        //        {
        //            CloseHandle(handle);
        //        }
        //        catch
        //        {
        //            MessageInfo(null, new MessageInfoEventArgs("关闭逻辑进程内存映射文件指针失败"));
        //        }
        //    }
        //}

        //static public bool WriteMeroryMappiong(int StartAddr, int Length, byte[] WriteBuf)
        //{
        //    IntPtr handle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, false, MF_MappingName);
        //    if (handle != IntPtr.Zero)
        //    {
        //        try
        //        {
        //            IntPtr mappingFile = MapViewOfFile(handle, FILE_MAP_WRITE, 0, 0, new IntPtr(0));
        //            IntPtr AcPtr = mappingFile + StartAddr;
        //            Marshal.Copy(WriteBuf, 0, AcPtr, Length);
        //            FlushViewOfFile(AcPtr, new IntPtr(Length));

        //            UnmapViewOfFile(mappingFile);
        //            UnmapViewOfFile(AcPtr);
        //            CloseHandle(handle);
        //            return true;
        //        }
        //        catch
        //        {
        //            MessageInfo(null, new MessageInfoEventArgs("写入逻辑进程内存映射文件失败"));
        //            Console.WriteLine("内存映射文件写入失败");
        //            return false;
        //        }
        //    }
        //    return false;
        //}
        //#endregion

        //---------------以下为管道接收数据处理
        static private void PipeDisposeHeartData(byte[] Buf, int length)    //逻辑处理层心跳信息
        {
            if (Buf[0] == 0x6f && Buf[1] == 0x00)
            {
                c_SendData.SendHartData();      //收到心跳信息，则发送心跳信息
            }
        }
        static private void PipeDisposeCommandRet(byte[] Buf, int length)   //逻辑处理命令回执信息
        {
            int type = Buf[1];
            objRevCommandType tmp = new objRevCommandType();
            tmp.type = type;
            tmp.length = length - 3;    //前面两字节包头+命令类型
            for (int i = 3; i < tmp.length; i++)
            {
                tmp.value.Add(Buf[i]);
            }
            NewCommandRet(tmp, new EventArgs());            
        }
        static private void PipeDisposeRealTimeAnalog(byte[] Buf, int Inlength)
        {
            //前两字节为类型
            int Length = Buf[2] + Buf[3] * 256;             //模拟量数据总长度
            if (Length != Inlength - 4)
            {
                Console.WriteLine("模拟量数据长度错误");
                return;
            }
            int Offset = 4;
            while (true)
            {
                if (Offset >= Inlength) break;
                byte AnalogType = Buf[Offset++];            //模拟量类型
                if (!c_Device.IsValidAnalogType((int)AnalogType))
                {
                    Console.WriteLine("模拟量类型错误");
                    break;
                }
                int AnalogLength = Buf[Offset] + (Buf[Offset + 1]<<8);   //单项模拟量长度
                Offset += 2;
                objRevAnalogType tmp = new objRevAnalogType();
                string KeyString = c_Device.GetAnalogTypeName((AnalogCodeType)AnalogType);
                //tmp.AnalogTypeName = KeyString;
                tmp.AnalogType = AnalogType;
                for (int i = 0; i < AnalogLength/2; i++)
                {
                    Int16 TmpValue = (Int16)(Buf[Offset] + Buf[Offset + 1] * 256);
                    tmp.ValueList.Add(TmpValue);
                    Offset += 2;
                }
                NewAnalogEvent(tmp, new EventArgs());
            }
        }
        static private void PipeDisposeRealTimeKGL(byte[] Buf, int Inlength)
        {
            int m = 2;
            objRevKGL t = new objRevKGL();
            t.AllFlag = true;
            t.kglNum = Buf[m] + (Buf[m + 1] << 8);
            m += 2;
            t.time = MySql.DateTimeToTime_t(DateTime.Now);
            int Length = 0;
            Length = t.kglNum / 8;
            if (t.kglNum % 8 != 0) Length++;    //非整数字节数，字节数++
            for (int i = 0; i < Length; i++)
            {
                t.Value.Add(Buf[m + i]);
            }
            NewKglEvent(t, new EventArgs());            
        }
        static private void PipeDisposeChangeKgl(byte[] Buf, int length)
        {
            int m = 2;
            objRevKGL t = new objRevKGL();
            t.AllFlag = false;
            t.kglNum = Buf[m] + (Buf[m + 1] << 8);
            m += 2;
            t.time = Buf[m] + (Buf[m + 1] << 8) + (Buf[m + 2] << 16) + (Buf[m + 3] << 24);
            m += 4;
            for (int i = 0; i < t.kglNum; i++)
            {
                t.Value.Add(Buf[m + i]);
            }
            NewKglEvent(t, new EventArgs());
        }
        static private void PipeDisposeRealTimeLK(byte[] Buf, int length)
        {
            objRevLkType obj = new objRevLkType();
            int type = Buf[1];
            string s = "";
            if (type == 1) s = "硬件平台A";
            else if (type == 2) s = "硬件平台B";
            else if (type == 3) s = "联锁接口进路信息";
            else if (type == 4) s = "联锁改方命令信息";
            else if (type == 5) s = "联锁改方回执信息";
            else if (type == 6) s = "站间改方命令";
            else if (type == 7) s = "站间改方回执";
            else if (type == 8) s = "站间边界信息";
            else if (type == 9) s = "临时限速状态";
            else if (type == 10) s = "轨道区段编码信息";
            else if (type == 11) s = "状态全体信息";
            else if (type == 12) s = "应答器报文编码信息";
            else if (type == 13) s = "无配线站方向口信息";

            obj.LkTypeName = s;
                        
            byte[] tmpBuf = new byte[length-2];
            Array.Copy(Buf, 2, tmpBuf, 0, length-2);
            obj.ValueList = tmpBuf.ToList();
            NewLkInfo(obj, new EventArgs());            
        }
        //static private void PipeDisposeGybdcqxData(byte[] Buf, int length)
        //{
        //    objRevGybdcQxType obj = new objRevGybdcQxType();
        //    obj.devNo = Buf[2] + (Buf[3] << 8);
        //    obj.time = Buf[4] + (Buf[5] << 8) + (Buf[6] << 16) + (Buf[7] << 24);
        //    obj.dotNum = Buf[8] + (Buf[9] << 8);
        //    int m = 10;
        //    for (int i = 0; i < obj.dotNum * 2; i++)
        //    {
        //        obj.v.Add(Buf[m++]);
        //    }
        //    lock (RevGybdcQxQueue)
        //    {
        //        RevGybdcQxQueue.Enqueue(obj);
        //    }
        //}
        /// <summary>
        /// 收到回执后，删除发送给服务器的报警数据
        /// </summary>
        /// <param name="obj"></param>
        static public void DeleteSevRTalarmData(Object sender, EventArgs e)
        {
            ObjAlaram obj = sender as ObjAlaram;
            if (Monitor.TryEnter(SendSevAlarmData, 500))
            {
                for (int i = 0; i < SendSevAlarmData.Count; i++)
                {
                    objSendAlarmData s = SendSevAlarmData[i];
                    if (s.alarm.u_time == obj.u_time && s.alarm.dev_type == obj.dev_type && s.alarm.dev_no == obj.dev_no)
                    {
                        SendSevAlarmData.Remove(s);
                        break;
                    }
                }
                Monitor.Exit(SendSevAlarmData);
            }
        }
        /// <summary>
        /// 报警数据发送给服务器
        /// </summary>
        /// <param name="obj"></param>
        static public void SendSevRealTimeAlarmData(ObjAlaram obj)
        {
            string Scode = c_Config.sysConfig.SevTelexCode;
            byte atype = obj.AlarmType;
            int rnum = 1;
            List<byte> li = MySql.objAlarmToByteBuf(obj, 0, 0);

            c_NetCom.AlarmRealtimeValue(Scode, atype, rnum, li);

            objSendAlarmData k = new objSendAlarmData();
            k.sendtime = DateTime.Now;
            k.alarm = obj;
            if(Monitor.TryEnter(SendSevAlarmData,500))
            {
//                SendSevAlarmData.Add(k);
                Monitor.Exit(SendSevAlarmData);
            }
        }
        /// <summary>
        /// 处理报警信息
        /// </summary>
        /// <param name="Buf"></param>
        /// <param name="length"></param>
        static private void PipeDisposeAlarmData(byte[] Buf, int length)
        {
            List<ObjAlaram> li = MySql.byteBufToObjAlarmList(Buf, 2, 0, 0);

            if (NewAlarmEvent != null)
            NewAlarmEvent(li, new EventArgs());
            
            c_SendData.SendAffirmAlarmData(li);         //发送给逻辑层，显示层已经收到报警信息。
            for (int i = 0; i < li.Count; i++)
            {
//                SendSevRealTimeAlarmData(li[i]);
            }            
        }
        /// <summary>
        /// 实时状态处理
        /// </summary>
        /// <param name="Buf"></param>
        /// <param name="length"></param>
        static private void PipeDisposeStatueData(byte[] Buf, int length)
        {
            List<byte> li = new List<byte>();
            for(int i = 2;i<length;i++)
            {
                li.Add(Buf[i]);
            }
            NewStatueInfo(li, new EventArgs());
        }
        //-----------
        //-------数据处理函数入口，管道接收线程调用
        static public void DisposeRevPipeData(byte[] revBuf, int length)
        {
            int flag0 = revBuf[0];
            int flag1 = revBuf[1];
            if (flag0 == 0x6f && flag1 == 0x00) PipeDisposeHeartData(revBuf, length);           //心跳
            else if (flag0 == 0x8f) PipeDisposeCommandRet(revBuf, length);     //命令回执信息
            else if (flag0 == 0x90 && flag1 == 0x01) PipeDisposeRealTimeKGL(revBuf, length);     //开关量实时值
            //else if (flag0 == 0x90 && flag1 == 0x02) PipeDisposeChangeKgl(revBuf, length);
            else if (flag0 == 0x90 && flag1 == 0x02) PipeDisposeRealTimeAnalog(revBuf, length);     //模拟量实时值
            
            else if (flag0 == 0x90 && flag1 == 0x03) PipeDisposeAlarmData(revBuf, length);     //报警实时值处理
            else if (flag0 == 0x90 && flag1 == 0x04) PipeDisposeStatueData(revBuf, length);     //实时状态处理
            else if (flag0 == 0xa0) PipeDisposeRealTimeLK(revBuf, length);
        }
        
        static private void NewPipeEvent(Object sender, EventArgs e)
        {
            List<byte> li = (List<byte>)sender;
            DisposeRevPipeData(li.ToArray(), li.Count);
        }
        /// <summary>
        /// 刷新发送给服务器的实时报警值，发送后超过3分钟，如果没有收到回执，则继续发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static private void RefreshSendAlarmData(object sender, System.Timers.ElapsedEventArgs e)
        {
            if(Monitor.TryEnter(SendSevAlarmData,500))
            {
                for (int i = 0; i < SendSevAlarmData.Count; i++)
                {
                    objSendAlarmData obj = SendSevAlarmData[i];
                    TimeSpan t = DateTime.Now.Subtract(obj.sendtime);
                    if (t.TotalMinutes >= 3)
                    {
                        SendSevRealTimeAlarmData(obj.alarm);
                        obj.sendtime = DateTime.Now;
                    }
                }
                Monitor.Exit(SendSevAlarmData);
            }
        }

        
        static public void StartRevPipeData()
        {
            c_NetData.EventRevSevAlarmRet += DeleteSevRTalarmData;
            C_MyPipe.NewPipeDataEvent += NewPipeEvent;
            
            Time_CheckSendSevAlarm.AutoReset = true;
            Time_CheckSendSevAlarm.Interval = 1000*60*3;
            Time_CheckSendSevAlarm.Elapsed += new System.Timers.ElapsedEventHandler(RefreshSendAlarmData);
            Time_CheckSendSevAlarm.Start();
        }
    }

    public static class C_MyPipe        //管道
    {
        #region 管道API引用
        public const uint NMPWAIT_WAIT_FOREVER = 0xffffffff;
        public const uint FILE_FLAG_OVERLAPPED = 0x40000000;
        public const uint PIPE_ACCESS_DUPLEX = 0x00000003;
        public const uint PIPE_READMODE_MESSAGE = 0x00000002;
        public const uint PIPE_TYPE_MESSAGE = 0x00000004;
        public const uint PIPE_WAIT = 0x00000000;
        public const uint PIPE_UNLIMITED_INSTANCES = 255;
        public const int INVALID_HANDLE_VALUE = -1;
        public const ulong ERROR_PIPE_CONNECTED = 535;
        public const uint GENERIC_WRITE = (0x40000000);
        public const uint GENERIC_READ = (0x80000000);
        public const uint OPEN_EXISTING = 3;
        public const ulong ERROR_PIPE_BUSY = 231;
        public const uint FILE_SHARE_READ = 0x00000001;
        public const uint FILE_SHARE_WRITE = 0x00000002;
        public const uint FILE_SHARE_DELETE = 0x00000004;
        public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr CreateFile(
            String lpFileName,						  // file name
            uint dwDesiredAccess,					  // access mode
            uint dwShareMode,								// share mode
            IntPtr attr,				// SD
            uint dwCreationDisposition,			// how to create
            uint dwFlagsAndAttributes,			// file attributes
            IntPtr hTemplateFile);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr CreateNamedPipe(
            String lpName,									// pipe name
            uint dwOpenMode,								// pipe open mode
            uint dwPipeMode,								// pipe-specific modes
            uint nMaxInstances,							// maximum number of instances
            uint nOutBufferSize,						// output buffer size
            uint nInBufferSize,							// input buffer size
            uint nDefaultTimeOut,						// time-out interval
            //IntPtr pipeSecurityDescriptor
            SecurityAttributes pipeSecurityDescriptor		        // SD
            );


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool ConnectNamedPipe(
            IntPtr hHandle,									// handle to named pipe
            Overlapped lpOverlapped					// overlapped structure
            );


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool ReadFile(
            IntPtr hHandle,											// handle to file
            byte[] lpBuffer,								// data buffer
            uint nNumberOfBytesToRead,			// number of bytes to read
            byte[] lpNumberOfBytesRead,			// number of bytes read
            uint lpOverlapped								// overlapped buffer
            );


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WriteFile(
            IntPtr hHandle,											// handle to file
            byte[] lpBuffer,							  // data buffer
            uint nNumberOfBytesToWrite,			// number of bytes to write
            byte[] lpNumberOfBytesWritten,	// number of bytes written
            uint lpOverlapped								// overlapped buffer
            );
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool PeekNamedPipe(
            IntPtr hNamedPipe,      //管道句柄
            byte[] lpBuffer,        //读取输出缓冲区，可选
            uint nBufferSize,       //缓冲区大小
            ref uint lpBytesRead,       //接收从管道中读取数据的变量的指针，可选
            ref uint lpTotalBytesAvail, //接收从管道读取的字节总数
            ref uint lpBytesLeftThisMessage
            );

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool FlushFileBuffers(
            IntPtr hHandle);


        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool DisconnectNamedPipe(
            IntPtr hHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool SetNamedPipeHandleState(
            IntPtr hHandle,
            ref uint mode,
            IntPtr cc,
            IntPtr cd);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool WaitNamedPipe(
            String name,
            uint timeout);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool CloseHandle(
            IntPtr hHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern uint GetLastError();

        //[StructLayout(LayoutKind.Sequential)]
        //public struct SecurityAttributes
        //{
        //    public int nLength;
        //    public IntPtr lpSecurityDescriptor;
        //    public int bInheritHandle;
        //}
        //[StructLayout(LayoutKind.Sequential)]
        //public struct Overlapped
        //{
        //    public IntPtr Internal;
        //    public IntPtr InternalHigh;
        //    public int Offset;
        //    public int OffsetHigh;
        //    public IntPtr hEvent;
        //}
        [StructLayout(LayoutKind.Sequential)]
        public class Overlapped
        {
        }

        [StructLayout(LayoutKind.Sequential)]
        public class SecurityAttributes
        {
        }
        #endregion
        
        static string strPipeName = "\\\\.\\pipe\\CSM2010pipe";
        //static string strPipeName = "\\\\1af1917e1b90403\\pipe\\test6pipe";
        static IntPtr fileHandle = IntPtr.Zero;
        static public bool ReadPipeConnect = false;     //读管道连接成功标志

        static string strSendPipeName = "\\\\.\\pipe\\DisplayPipe";
        //static string strSendPipeName = "\\\\.\\pipe\\test10pipe";
        static IntPtr fileHandleSend = IntPtr.Zero;
        static public bool SendPipeConnect = false;     //写管道连接成功标志

        static public EventHandler NewPipeDataEvent;    //收到管道数据的消息
        static private bool readData = true;            //管道读线程标志
        static public EventHandler PipeErrorEvent;      //管道错误消息
        /// <summary>
        /// 线程关闭函数.
        /// </summary>
        static public void StopPipeThread()
        {
            readData = false;
        }
        static private void WaitMyNamePipe(object o)
        {
            ReadPipeConnect = false;
            while (true)
            {
                if (!WaitNamedPipe(strPipeName, NMPWAIT_WAIT_FOREVER))
                {
                    Thread.Sleep(500);
                }
                else
                {
                    fileHandle = CreateFile(strPipeName, GENERIC_READ | GENERIC_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
                    
                    if (fileHandle.ToInt32() == INVALID_HANDLE_VALUE)
                    {
                        uint k = GetLastError();
                        Console.WriteLine(string.Format("不能打开管道{0}",k));
                        continue;
                    }
                    
                    uint pipeMode = PIPE_READMODE_MESSAGE;
                    bool success = SetNamedPipeHandleState(fileHandle, ref pipeMode, IntPtr.Zero, IntPtr.Zero);
                    if (!success)
                    {
                        Console.WriteLine("设置管道状态失败");
                        return;
                    }
                    ReadPipeConnect = true;
                    Console.WriteLine("接收管道连接成功");
                    break;
                }
            }
        }

        static private void CreateSendPile(object o)
        {            
            SendPipeConnect = false;
            fileHandleSend = CreateNamedPipe(strSendPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
                                            1024 * 1024, 1024 * 1024, NMPWAIT_WAIT_FOREVER, null);
            if (fileHandleSend.ToInt32() == INVALID_HANDLE_VALUE)
            {
                uint u = GetLastError();
                Console.WriteLine("不能建立管道");
                return;
            }
            Console.WriteLine("建立发送管道成功");
            SendPipeConnect = ConnectNamedPipe(fileHandleSend, null);	//等待连接
            Console.WriteLine("发送管道连接成功");
        }

        static public void StartPipeClient()
        {
            string hostname = System.Net.Dns.GetHostName();
            ThreadPool.QueueUserWorkItem(new WaitCallback(WaitMyNamePipe), null);           //等待接收管道
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadData_Pipe), fileHandle);

            ThreadPool.QueueUserWorkItem(new WaitCallback(CreateSendPile), null);           //建立发送管道
        }

        static public bool WritePipeData(byte[] Buf, int length)
        {
            byte[] SendBuf = new byte[length + 4];
            SendBuf[0] = (byte)(length & 0xff);
            SendBuf[1] = (byte)(length >> 8 & 0xff);
            SendBuf[2] = (byte)(length >> 16 & 0xff);
            SendBuf[3] = (byte)(length >> 24 & 0xff);
            Array.Copy(Buf, 0, SendBuf, 4, length);
            //Buf.CopyTo(SendBuf, 4);

            if (SendPipeConnect)
            {
                byte[] a = new byte[4];
                try
                {
                    bool b = WriteFile(fileHandleSend, SendBuf, (uint)(length + 4), a, 0);
                    if (!b)
                    {
                        Console.WriteLine("管道写错误");
                        DisconnectNamedPipe(fileHandleSend);
                        CloseHandle(fileHandleSend);
                        Console.WriteLine("重新建立发送管道");
                        SendPipeConnect = false;
                        ThreadPool.QueueUserWorkItem(new WaitCallback(CreateSendPile), null);
                        return false;
                    }
                    else Console.WriteLine(string.Format("管道写字节{0}",length+4));
                    return true;
                }
                catch
                {
                    Console.WriteLine("error:写管道系统错误");
                }
            }
            return false;
        }
     

        static private void ThreadReadData_Pipe(object o)
        {
            while (readData)
            {
                if (ReadPipeConnect)
                {
                    bool ReadFlag = true;
                    byte[] numReadWritten = new byte[4];
                    byte[] intBytes = new byte[4];
                    byte[] readSize = new byte[4];
                    byte[] recBuffer;
                    try
                    {
                        ReadFlag = ReadFile(fileHandle, intBytes, 4, numReadWritten, 0);
                        uint u = GetLastError();
                        int Datalen = BitConverter.ToInt32(intBytes, 0);
                        if (Datalen > 0)
                        {
                            recBuffer = new byte[Datalen];
                            readSize.Initialize();
                            ReadFlag = ReadFile(fileHandle, recBuffer, (uint)Datalen, readSize, 0);
                            int len = BitConverter.ToInt32(readSize, 0);
                            if (ReadFlag && len > 0)
                            {
                                List<byte> li = new List<byte>();
                                li.AddRange(recBuffer);
                                NewPipeDataEvent(li, new EventArgs());  //把收到的数据以消息形式发送出去
                                
                                Console.WriteLine(string.Format("收到管道数据:{0}", len));
                            }
                        }
                    }
                    catch(Exception e)
                    {
                        Console.WriteLine("管道读错误");
                        PipeErrorEvent("管道读错误", new EventArgs());
                    }

                    if (!ReadFlag)
                    {
                        Console.WriteLine("管道读错误");
                        PipeErrorEvent("管道读错误", new EventArgs());
                        try
                        {
                            CloseHandle(fileHandle);
                        }
                        catch(Exception e)
                        { }
                        ReadPipeConnect = false;
                        ThreadPool.QueueUserWorkItem(new WaitCallback(WaitMyNamePipe), null);
                    }
                }
                else Thread.Sleep(500);
            }
        }
    }
}
